import { addInfo, delInfo } from "@/api/modules/iot/variable";
import { replaceProfile } from "@/api/modules/model/profile";
import { replaceSchema } from "@/api/modules/model/schema";
import { setSensor } from "@/api/modules/model/sensor";
import DialogBox from "@/components/DialogBox";
import { JsonSchemaEmitParam } from "@/components/JsonSchemaForm/interface/jsonschema";
import JsonSchemaEditor from "@/components/JsonSchemaForm/JsonSchemaForm.vue";
import { ResultEnum } from "@/enums/httpEnum";
import { MessageType } from "@/enums/messageEnum";
import { AuthBtns, SchemaNodeKey, SchemaNodeType } from "@/utils/constants";
import mittBus from "@/utils/mittBus";
import { assJsonpathData, showMsg, showTips } from "@/utils/util";
import jsonpath from "jsonpath";
import { getCurrentInstance, defineComponent, ComponentInternalInstance } from "vue";
import { useRoute } from "vue-router";

import {
	parseDeviceSchemaFromSensor,
	parseProfileFromDeviceSensorParam,
	parseProfileFromRealtimeSensorValue,
	parseSchemaFromDevice,
	parseSchemaFromGatewaySensor
} from "../../../../utils/schema";
import SensorHistory from "./SensorHistory";
import { GatewayType } from "@/api/interface/iot";

/**
 * 设备参数信息,scheme中的config下面子设备参数信息（排除sensor节点）
 * 相关参数：设备接入端口、地址、采集周期、上报周期
 */
export default defineComponent({
	props: {
		type: {
			type: String,
			default() {
				return GatewayType.Device;
			}
		}
	},
	emits: [],
	setup() {
		const { proxy } = getCurrentInstance() as ComponentInternalInstance;
		const route = useRoute();

		//设备参数配置模型
		const schema = inject<any>(SchemaNodeKey.schema);
		const gatewaySchema = inject<any>(SchemaNodeKey.gatewaySchema);
		const profile = inject<any>(SchemaNodeKey.profile);
		const disabledMod = inject<any>(AuthBtns.disabledMod);

		const state = reactive({
			sn: (route.query.sn || route.query.id) as string
		});
		//变量模型profile：单位、名称、描述等
		let sensorRealtimeValue = ref<any>({});
		let sensorProfile = ref<any>({});
		const refreshDeviceDetail = () => {
			if (route.query.id) {
				mittBus.emit("refreshProductDetail");
			} else if (route.query.type) {
				mittBus.emit("refreshGatewayDetail");
			} else {
				mittBus.emit("refreshDeviceDetail");
			}
		};
		const saveSchema = () => {
			if (disabledMod.value) return;
			replaceSchema({
				idSn: state.sn,
				nodePath: "properties.sensor",
				data: {
					type: "object",
					title: schema.value?.properties?.sensor?.title || "传感量",
					properties: schemaTree.root.properties
				}
			}).then(res => {
				let ok = res.code == ResultEnum.SUCCESS;
				if (ok) {
					// replaceProfile({ idSn: state.sn, data: sensorProfile.value, nodePath: "config.sensor" }).then(res => {
					// 	let ok = showTips(res.code, "设备配置", res.message);
					// 	if (ok) {
					refreshDeviceDetail();
					// }
					// });
				}
			});
		};
		// if (!Object.keys(sensorRealtimeValue).length && import.meta.env.DEV) {
		// 	sensorRealtimeValue = {import { img } from '@/assets/images/500.png';

		// 		...sensorRealtimeValue,
		// 		k3: 33,
		// 		video: "http://xxx.xxx.flv",
		// 		latlng: { lat: 31.313048, lng: 121.299517 },
		// 		web: "http://baidu.com"
		// 	};
		// }

		//缓存sensor数据
		const schemaTree = reactive({
			root: {
				type: "object",
				title: schema.value?.properties?.config?.properties?.sensor?.title || "设备模型",
				properties: {},
				required: []
			}
		});
		const schemaTreeCopy = ref({});
		const sensorHistoryEl = ref();
		onBeforeMount(() => {
			initSensor();
			if (isSensor.value) {
				saveSchema();
			}
			//监听树历史数据图标点击
			mittBus.on("clickValueIcon", data => {
				let param = data as JsonSchemaEmitParam;
				sensorHistoryEl.value.loadData(param, state.sn);
			});
			//监听新增节点
			mittBus.on("addJsonValue", async (data: any) => {
				if (setProfileDialog.visible) return;
				if (route.query.sn) {
					let { code, message } = await addInfo({
						sn: route.query.sn as string,
						key: data.path,
						label: data.label || data.key,
						type: data.type
					});
					let ok = code == ResultEnum.SUCCESS;
					// let ok = showTips(code, "新增参数", message);
					if (ok) {
						saveProfile(true);
					} else {
						showMsg(message, MessageType.error);
					}
				} else {
					saveSchema();
				}
			});
			//监听删除节点

			mittBus.on("delJsonValue", async (data: any) => {
				if (setProfileDialog.visible) return;
				if (route.query.sn) {
					let { code, message } = await delInfo({ snKey: { [route.query.sn as string]: [data] } });
					let ok = showTips(code, "删除参数", message);
					if (ok) {
						// saveProfile(true, true);
						refreshDeviceDetail();
					}
				} else {
					saveSchema();
				}
			});
			//监听变量配置返回数据处理
			mittBus.on("clickSensorParam", (path: any) => {
				sensorFormDialog.path = path;
				const sensorTemplate = parseSchemaFromDevice(schema.value)?.sensor?.properties || {};
				let pathSensor = jsonpath.query(sensorTemplate, assJsonpathData(path.replaceAll(".", ".properties.")));
				if (pathSensor.length && pathSensor[0].properties) {
					sensorFormDialog.schema.root = {
						...pathSensor[0],
						title: path,
						type: SchemaNodeType.object
					};
					sensorFormDialog.currentSchema = JSON.stringify(sensorFormDialog.schema);
					sensorFormDialog.currentDetail = JSON.stringify(sensorFormDialog.detail);
				} else {
					//网关和设备的变量配置都为空的时候插入空root
					sensorFormDialog.schema.root =
						JSON.stringify(parseSchemaFromGatewaySensor(gatewaySchema.value).properties) == "{}"
							? {
									title: path,
									type: SchemaNodeType.object,
									properties: {
										calc: {
											type: "object",
											properties: {
												base: {
													type: "number",
													title: "基础值"
												},
												mult: {
													type: "number",
													title: "倍率"
												},
												decimal: {
													type: "number",
													title: "小数位"
												}
											}
										},
										type: {
											type: "string",
											title: "数据类型"
										},
										unit: {
											type: "string",
											title: "单位"
										},
										param: {
											type: "object",
											properties: {
												reg: {
													type: "number",
													title: "寄存器地址"
												},
												read: {
													type: "number",
													title: "寄存器类型"
												},
												write: {
													type: "number",
													title: "寄存器写类型"
												}
											}
										}
									},
									required: []
							  }
							: parseSchemaFromGatewaySensor(gatewaySchema.value);
					sensorFormDialog.currentSchema = "";
					sensorFormDialog.currentDetail = "";
				}
				sensorFormDialog.detail = jsonpath.query(sensorProfile.value, assJsonpathData(path)).length
					? jsonpath.query(sensorProfile.value, assJsonpathData(path))[0]
					: {};
				sensorFormDialog.visible = true;
			});
		});

		onBeforeUnmount(() => {
			mittBus.off("clickSensorParam");
			mittBus.off("clickValueIcon");
			mittBus.off("addJsonValue");
			mittBus.off("delJsonValue");
		});
		watch(
			() => schema.value,
			() => {
				initSensor();
			}
		);
		const isSensor = ref(false);
		//初始化上报数据，没有模型就自动增加
		const initSensor = async () => {
			//变量模型profile：单位、名称、描述等
			sensorRealtimeValue.value = parseProfileFromRealtimeSensorValue(profile.value);
			sensorProfile.value = parseProfileFromDeviceSensorParam(profile.value);
			const sensorSchema = parseDeviceSchemaFromSensor(schema.value);
			isSensor.value = JSON.stringify(sensorSchema) == "{}";
			schemaTree.root.properties = sensorSchema;
			const applySchema = (value: any, path: string) => {
				//当前有相同Schema的key不执行
				// if (!jsonpath.query(sensorSchema, assJsonpathData(path)).length) {
				let obj = jsonpath.query(sensorSchema, assJsonpathData(path)).length
					? jsonpath.query(sensorSchema, assJsonpathData(path))[0]
					: {};
				obj.type = obj.type || typeof value;
				if (typeof value == "object" && obj.type == "object") {
					jsonpath.value(sensorSchema, assJsonpathData(path), { ...obj });
					for (let ck in value) {
						let cPath = path ? path + ".properties." + ck + "" : ck;
						jsonpath.value(sensorSchema, assJsonpathData(cPath));
						applySchema(value[ck], cPath);
					}
				} else {
					jsonpath.value(sensorSchema, assJsonpathData(path), { ...obj });
				}
				// }
			};
			for (let key in sensorRealtimeValue.value) {
				applySchema(sensorRealtimeValue.value[key], key);
			}
			schemaTreeCopy.value = JSON.parse(JSON.stringify(schemaTree));
		};

		//变量配置弹窗
		const sensorFormDialog = reactive({
			visible: false,
			schema: { root: {} },
			detail: {},
			title: "添加变量",
			path: "",
			currentSchema: "",
			currentDetail: ""
		});
		const setProfileDialog = reactive({ visible: false });
		const saveProfile = async (local = false, entire = false) => {
			setSensor({ idSn: state.sn, data: sensorRealtimeValue.value, local, entire }).then(res => {
				let ok = showTips(res.code, "参数配置", res.message);
				if (ok) {
					setProfileDialog.visible = false;
					refreshDeviceDetail();
				}
			});
		};
		//添加变量配置
		const addSensor = async () => {
			await saveSchema();
			sensorFormDialog.visible = false;
			if (sensorFormDialog.currentSchema != JSON.stringify(sensorFormDialog.schema)) {
				let data: any = {};
				jsonpath.value(
					data,
					assJsonpathData(sensorFormDialog.path.replaceAll(".", ".properties."), "$.."),
					sensorFormDialog.schema.root
				);
				let key = Object.keys(data)[0];
				let resSchema = await replaceSchema({
					idSn: state.sn,
					nodePath: `properties.config.properties.sensor.properties.${key}`,
					data: data[key]
				});
				if (sensorFormDialog.currentDetail != JSON.stringify(sensorFormDialog.detail)) {
					// let ok = showTips(resSchema.code, "变量配置", resSchema.message);
					let ok = resSchema.code == ResultEnum.SUCCESS;
					if (ok) {
						sensorFormDialog.currentSchema = JSON.stringify(sensorFormDialog.schema);
						// refreshDeviceDetail();
					} else {
						showMsg(resSchema.message, MessageType.error);
						return;
					}
				}
			}
			if (sensorFormDialog.currentDetail != JSON.stringify(sensorFormDialog.detail)) {
				let data: any = {};
				jsonpath.value(data, assJsonpathData(sensorFormDialog.path, "$.."), sensorFormDialog.detail);
				let key = Object.keys(data)[0];
				let resProfile = await replaceProfile({
					idSn: state.sn,
					nodePath: `config.sensor.${key}`,
					data: data[key]
				});
				let ok = showTips(resProfile.code, "变量配置", resProfile.message);
				if (ok) {
					sensorFormDialog.currentDetail = JSON.stringify(sensorFormDialog.detail);
					// refreshDeviceDetail();
				}
			}
			refreshDeviceDetail();
		};
		return () => {
			return (
				<div class="block-basic p-8">
					<SensorHistory ref={sensorHistoryEl} />
					<DialogBox
						title="变量配置"
						v-model:visible={sensorFormDialog.visible}
						footerLabel={["关闭", "保存"]}
						width="980px"
						onConfirm={() => addSensor()}
					>
						<JsonSchemaEditor
							class="w-full"
							value={sensorFormDialog.schema}
							lang="zh_CN"
							extType
							jsonValue={sensorFormDialog.detail}
							disabled={disabledMod.value}
						/>
					</DialogBox>
					<DialogBox
						title="数据下发"
						v-model:visible={setProfileDialog.visible}
						footerLabel={["关闭", "下发"]}
						width="980px"
						onConfirm={() => saveProfile()}
					>
						<JsonSchemaEditor class="w-full" value={schemaTreeCopy.value} lang="zh_CN" jsonValue={sensorRealtimeValue.value} />
					</DialogBox>
					<div class="flex mb-4 justify-between">
						<div class="flex">
							<el-button type="primary" plain onClick={() => saveSchema()} disabled={disabledMod.value}>
								{proxy?.$t("sensorformlist.btn.savemodel")}
							</el-button>
							{route.query.sn && (
								<el-button
									type="primary"
									plain
									onClick={() => {
										setProfileDialog.visible = true;
									}}
									disabled={disabledMod.value}
								>
									{proxy?.$t("sensorformlist.btn.data")}
								</el-button>
							)}
						</div>
						{/* <el-button class="ml-auto" link type="primary" onClick={() => (dialogVisible.value = true)}>
							预览JSON
						</el-button> */}
					</div>
					<JsonSchemaEditor
						isSensor
						class="w-full"
						value={schemaTree}
						lang="zh_CN"
						custom
						jsonParam={sensorProfile.value}
						jsonValue={sensorRealtimeValue.value}
						disabled={disabledMod.value}
					/>
				</div>
			);
		};
	}
});
